package com.golang.api.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.golang.api.common.ActivityStatusType;
import com.golang.api.common.SerialCodePrefix;
import com.golang.api.common.domain.PageDTO;
import com.golang.api.domain.*;
import com.golang.api.dto.request.*;
import com.golang.api.dto.response.*;
import com.golang.api.repository.ActivityRepository;
import com.golang.api.service.IActivityService;
import com.golang.api.util.Result;
import com.golang.api.util.ResultGenerator;
import com.golang.api.util.ServiceException;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 活动Service业务层处理
 *
 * @author ruoyi
 * @date 2025-01-12
 */
@Service
@Slf4j
public class ActivityServiceImpl implements IActivityService {

    @Resource
    ActivityRepository activityRepository;

    @Override
    public Result<PageDTO<ActivityListRespDto>> list(ActivitySearchDto query) {
        PageDTO<ActivityListRespDto> result = new PageDTO<ActivityListRespDto>().setTotalCount(0L).setList(Lists.newArrayList());
        IPage<Activity> page = activityRepository.queryActivityInfoPage(query);
        if (page.getRecords().size() <= 0) {
            return ResultGenerator.success(result);
        }

        return ResultGenerator.success(result.setTotalCount(page.getTotal()).setList(pageInfos2Items(page.getRecords()).apply(page.getRecords())));
    }

    @Override
    public Result<String> createBasic(ActivityBasicDto basic) throws JsonProcessingException {

        ObjectMapper objectMapper = new ObjectMapper();
        List<ActivityProcessDto> processList = objectMapper.readValue(basic.getProcessList(), objectMapper.getTypeFactory().constructCollectionType(List.class, ActivityProcessDto.class));
        List<ActivityTagDto> tagList = objectMapper.readValue(basic.getTagList(), objectMapper.getTypeFactory().constructCollectionType(List.class, ActivityTagDto.class));
        List<String> picList = objectMapper.readValue(basic.getPicArr(), objectMapper.getTypeFactory().constructCollectionType(List.class, String.class));


        Activity activity = activityBasic(basic).apply(basic);

        boolean flag;

        if (activity.getId() == null) {
            flag = activityRepository.insertActivityBasic(activity) > 0;
        } else {
            activityRepository.deleteProcessByActivityId(basic.getActivityId());
            activityRepository.deleteTagByActivityId(basic.getActivityId());
            activityRepository.deletePicByActivityId(basic.getActivityId());

            flag = activityRepository.updateActivityBasic(activity) > 0;

        }

        if (flag) {
            processList.forEach(o -> {
                ActivityProcess process = activityProcessDto2ActivityProcess(o, activity.getActivityId()).apply(o);
                activityRepository.insertActivityProcess(process);
            });

            //保存标签
            tagList.forEach(o -> {
                ActivityTag tag = activityTagDto2ActivityTag(o, activity.getActivityId()).apply(o);
                activityRepository.insertActivityTag(tag);
            });

            //保存标签
            picList.forEach(o -> {
                ActivityPic pic = activityPicDto2ActivityPic(o, activity.getActivityId()).apply(o);
                activityRepository.insertActivityPic(pic);
            });
            return ResultGenerator.success(activity.getActivityId());
        }


        return null;

    }


    @Override
    public Result<ActivityBasicRespDto> getBasic(String activityId) {
        Activity entity = activityRepository.queryActivity(activityId);

        ActivityBasicRespDto activityBasicRespDto = ActivityBasic2Dto(entity).apply(entity);
        List<ActivityProcessRespDto> processDtoList = CollUtil.list(false);
        List<ActivityProcess> processList = activityRepository.queryActivityProcess(activityId);
        //流程列表
        processList.forEach(process -> {
            ActivityProcessRespDto processDto = ActivityProcess2Dto(process).apply(process);
            processDtoList.add(processDto);
        });

        activityBasicRespDto.setProcessList(processDtoList);

        List<ActivityTagRespDto> tagDtoList = CollUtil.list(false);
        List<ActivityTag> tagList = activityRepository.queryActivityTag(activityId);
        //标签列表
        tagList.forEach(tag -> {
            ActivityTagRespDto tagDto = ActivityTag2Dto(tag).apply(tag);
            tagDtoList.add(tagDto);
        });
        activityBasicRespDto.setTagList(tagDtoList);

        return ResultGenerator.success(activityBasicRespDto);

    }

    @Override
    public Boolean createSetting(ActivitySettingDto setting) throws JsonProcessingException {

        ObjectMapper objectMapper = new ObjectMapper();
        List<ActivityTicketDto> ticketList = objectMapper.readValue(setting.getTicketList(), objectMapper.getTypeFactory().constructCollectionType(List.class, ActivityTicketDto.class));


        Activity activity = activityRepository.queryActivity(setting.getActivityId());

        activity = activitySetting(setting, activity).apply(setting);

        boolean updateFlag = activityRepository.updateActivitySetting(activity) > 0;

        if (updateFlag) {

            activityRepository.deleteTicketByActivityId(activity.getActivityId());

            //保存票种配置信息
            Activity finalActivity = activity;
            ticketList.forEach(o -> {
                ActivityTicket ticket = activityTicketDto2ActivityTicket(o, finalActivity.getActivityId(), setting.getRefundDeadline()).apply(o);
                activityRepository.insertActivityTicket(ticket);
            });

            return true;

        }

        return false;
    }

    @Override
    public Result<Boolean> release(ActivitySettingDto setting) throws JsonProcessingException {
        if (createSetting(setting)) {
            Activity activity = activityRepository.queryActivity(setting.getActivityId());
            activity.setActivityStatus(ActivityStatusType.Progress.getDbType());
            activityRepository.updateActivitySetting(activity);
            return ResultGenerator.success(true);
        }
        return null;
    }

    @Override
    public Result<ActivitySettingRespDto> getSetting(String activityId) {
        Activity entity = activityRepository.queryActivity(activityId);

        ActivitySettingRespDto activitySettingRespDto = ActivitySetting2Dto(entity).apply(entity);
        List<ActivityTicketRespDto> ticketDtoList = CollUtil.list(false);
        List<ActivityTicket> ticketList = activityRepository.queryActivityTicket(activityId);
        //流程列表
        ticketList.forEach(ticket -> {
            ActivityTicketRespDto ticketDto = ActivityTicket2Dto(ticket).apply(ticket);
            ticketDtoList.add(ticketDto);
        });

        activitySettingRespDto.setTicketList(ticketDtoList);

        return ResultGenerator.success(activitySettingRespDto);
    }

    @Override
    public Result<ActivityDetailDto> info(String activityId) {

        Activity entity = activityRepository.queryActivity(activityId);

        if (Objects.isNull(entity))
            throw new ServiceException(500, "活动:" + activityId + "无效");

        ActivityDetailDto activityDetailDto = ActivityDetail2Dto(entity).apply(entity);


        List<ActivityProcessRespDto> processDtoList = CollUtil.list(false);
        List<ActivityProcess> processList = activityRepository.queryActivityProcess(activityId);
        //流程列表
        processList.forEach(process -> {
            ActivityProcessRespDto processDto = ActivityProcess2Dto(process).apply(process);
            processDtoList.add(processDto);
        });

        activityDetailDto.setProcessList(processDtoList);

        List<ActivityTicketInfoDto> ticketDtoList = CollUtil.list(false);
        List<ActivityTicket> ticketList = activityRepository.queryActivityTicket(activityId);
        //票种信息
        ticketList.forEach(ticket -> {
            ActivityTicketInfoDto ticketDto = ActivityTicketInfo2Dto(ticket).apply(ticket);
            ticketDtoList.add(ticketDto);
        });

        activityDetailDto.setTicketList(ticketDtoList);


        return ResultGenerator.success(activityDetailDto);
    }

    @Override
    @Transactional
    public Result<String> copyHistory(String activityId) {

        Activity activitySource = activityRepository.queryActivity(activityId);
        Activity activityTarget = new Activity();
        BeanUtil.copyProperties(activitySource, activityTarget);
        activityTarget.setId(null);
        activityTarget.setActivityId(SerialCodePrefix.splice(SerialCodePrefix.ACTIVITY_ID));
        activityTarget.setCreateTime(LocalDateTime.now());
        activityTarget.setUpdateTime(LocalDateTime.now());


        boolean insertFlag = activityRepository.insertActivityBasic(activityTarget) > 0;
        if (insertFlag) {

            List<ActivityProcess> processList = activityRepository.queryActivityProcess(activityId);
            List<ActivityTag> tagList = activityRepository.queryActivityTag(activityId);
            List<ActivityTicket> ticketList = activityRepository.queryActivityTicket(activityId);


            //保存活动流程
            processList.forEach(o -> {
                ActivityProcess processTarget = new ActivityProcess();
                BeanUtil.copyProperties(o, processTarget);
                processTarget.setId(null);
                processTarget.setActivityId(activityTarget.getActivityId());
                activityRepository.insertActivityProcess(processTarget);
            });

            //保存标签
            tagList.forEach(o -> {
                ActivityTag tagTarget = new ActivityTag();
                BeanUtil.copyProperties(o, tagTarget);
                tagTarget.setId(null);
                tagTarget.setActivityId(activityTarget.getActivityId());
                activityRepository.insertActivityTag(tagTarget);
            });

            //保存标签
            ticketList.forEach(o -> {
                ActivityTicket ticketTarget = new ActivityTicket();
                BeanUtil.copyProperties(o, ticketTarget);
                ticketTarget.setId(null);
                ticketTarget.setActivityId(activityTarget.getActivityId());
                activityRepository.insertActivityTicket(ticketTarget);
            });

            return ResultGenerator.success(activityTarget.getActivityId());
        }


        return ResultGenerator.error();
    }

    @Override
    public Result<Boolean> cancel(String activityId) {
        Activity activity = activityRepository.queryActivity(activityId);
        activity.setYn(0);
        activity.setActivityStatus(ActivityStatusType.Cancel.getDbType());
        activityRepository.updateActivitySetting(activity);

        return ResultGenerator.success(true);
    }

    @Override
    public Result<List<ActivityDetailDto>> recommend() {
        return null;
    }


}
